﻿namespace DistrRTgen
{
    using rtgen_worker;
    using System;
    using System.Threading;

    internal class ChainCheckHashThread : WorkThread
    {
        private Thread _Thread;
        public EventHandler _ThreadExited;
        private ChainCheckHash _Work;

        public ChainCheckHashThread(ChainCheckHash Work, EventHandler ThreadExited)
        {
            this._Work = Work;
            this._Thread = new Thread(new System.Threading.ThreadStart(this.ThreadStart));
            this._ThreadExited = ThreadExited;
        }

        public override void Start()
        {
            this._Thread.Start();
            this._Thread.Priority = ThreadPriority.Lowest;
        }

        public override void Stop()
        {
            this._Thread.Abort();
        }

        private void ThreadStart()
        {
            try
            {
                if (this._Work == null)
                {
                    Logger.AddLogLine("ChainChecker started with no work! Quitting", LoggerLevel.LOG_DEBUG);
                }
                else
                {
                    Logger.AddLogLine("Starting ChainChecker for RequestID " + this._Work.RequestID, LoggerLevel.LOG_DEBUG);
                    int nErrorCode = RainbowCrack.DoChainCheck(this._Work.Hash, this._Work.HashRoutine, this._Work.Charset, this._Work.MinLetters, this._Work.MaxLetters, this._Work.Index, this._Work.ChainLength, this._Work.Chains, this._Work.Password);
                    switch (nErrorCode)
                    {
                        case 1:
                            Logger.AddLogLine("Error occured in ChainChecker. Hash Routine " + this._Work.HashRoutine + " is not supported", LoggerLevel.LOG_ERROR);
                            break;

                        case 2:
                            Logger.AddLogLine("Error occured in ChainChecker. Charset " + this._Work.Charset + " is not supported", LoggerLevel.LOG_ERROR);
                            break;

                        case 3:
                            Logger.AddLogLine("Error occured in ChainChecker. Table Index " + this._Work.Index + " is invalid", LoggerLevel.LOG_ERROR);
                            break;
                    }
                    if (nErrorCode == 0)
                    {
                        Logger.AddLogLine("ChainChecker for RequestID " + this._Work.RequestID + " completed successfully", LoggerLevel.LOG_DEBUG);
                        if ((this._Work.Password != null) && (this._Work.Password != ""))
                        {
                            Logger.AddLogLine("Password for " + this._Work.HashRoutine + " " + this._Work.Hash + " is '" + this._Work.Password + "'", LoggerLevel.LOG_DEBUG);
                        }
                    }
                    this._Work.ErrorCode = nErrorCode;
                    this._ThreadExited(this, null);
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                Logger.AddLogLine(string.Concat(new object[] { "Error while doing ChainCheck on ", this._Work.RequestID, ": ", ex.Message }), LoggerLevel.LOG_ERROR);
                this._Work.ErrorCode = -1;
                this._ThreadExited(this, null);
            }
        }

        public ChainCheckHash Work
        {
            get
            {
                return this._Work;
            }
        }
    }
}

